package cn.kgc.springbootdemo.util;

import cn.hutool.core.util.StrUtil;
import cn.kgc.springbootdemo.constant.CommonConstants;
import cn.kgc.springbootdemo.enums.ResultEnum;
import cn.kgc.springbootdemo.exception.HandleException;
import lombok.experimental.UtilityClass;
import org.springframework.data.redis.RedisSystemException;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.sql.SQLSyntaxErrorException;
import java.util.Objects;

/**
 * <h3>springbootdemo</h3>
 * <p>抛出异常工具类</p>
 *
 * @author : DongZeJian
 * @date : 2020-05-21 11:12
 **/
@UtilityClass
public class ExtApiExceptionUtils {

    /**
     * 抛出Throwable异常
     *
     * @param throwable
     */
    public void throwThrowableException(Throwable throwable) {
        if (throwable instanceof RedisSystemException) {
            throw new HandleException(ResultEnum.ERROR_CODE.getCode(), ResultEnum.REDIS_ERROR.getMessage());
        }
        if (throwable instanceof SQLSyntaxErrorException) {
            throw new HandleException(ResultEnum.ERROR_CODE.getCode(), ResultEnum.MYSQL_ERROR.getMessage());
        }
        if (throwable instanceof HandleException) {
            throw new HandleException(((HandleException) throwable).getCode(), throwable.getMessage());
        }
        if (throwable instanceof RuntimeException) {
            throw new HandleException(ResultEnum.ERROR_CODE.getCode(), ResultEnum.INTER_ERROR.getMessage());
        }
    }

    /**
     * 抛出Exception异常
     *
     * @param e
     */
    public void throwException(Exception e) {
        if (e instanceof SQLSyntaxErrorException) {
            throw new HandleException(ResultEnum.ERROR_CODE.getCode(), ResultEnum.MYSQL_ERROR.getMessage());
        }
        if (e instanceof RedisSystemException) {
            throw new HandleException(ResultEnum.ERROR_CODE.getCode(), ResultEnum.REDIS_ERROR.getMessage());
        }
        if (e instanceof HandleException) {
            throw new HandleException(((HandleException) e).getCode(), e.getMessage());
        }
        if (e instanceof RuntimeException) {
            throw new HandleException(ResultEnum.ERROR_CODE.getCode(), ResultEnum.INTER_ERROR.getMessage());
        }
    }


    /**
     * 根据Exception异常获取堆栈详细信息
     *
     * @param exception : Exception异常对象
     * @return 返回堆栈信息
     */
    public String getExceptionAllinformation(Exception exception) {
        return getQingduoStackTrace(exception);
    }

    /**
     * 根据Exception异常获取堆栈详细信息
     *
     * @param exception : Exception异常对象
     * @return 返回堆栈信息前500个字符
     */
    public String getException500information(Exception exception) {
        String qingduoStackTrace = getQingduoStackTrace(exception);
        if (StrUtil.isEmpty(qingduoStackTrace)) {
            return null;
        }
        int length = qingduoStackTrace.length();
        //如果堆栈异常信息字符串长度小于500将全部返回、否则截取前500返回
        if (length <= CommonConstants.EXCEPTION_MSG_MAX) {
            return qingduoStackTrace;
        }
        return qingduoStackTrace.substring(0, CommonConstants.EXCEPTION_MSG_MAX);
    }

    /**
     * 封装根据Exception异常获取堆栈详细信息
     *
     * @param exception : Exception异常对象
     * @return 返回详细堆栈信息
     */
    private String getQingduoStackTrace(Exception exception) {
        if (Objects.isNull(exception)) {
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        PrintStream pout = new PrintStream(out);
        exception.printStackTrace(pout);
        String ret = new String(out.toByteArray());
        if (Objects.nonNull(pout)) {
            pout.close();
        }
        if (Objects.nonNull(out)) {
            try {
                out.close();
            } catch (Exception e) {
            }
        }
        return ret;
    }
}
